package com.hh.bidding.service.business;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

/**
 * 供应商竞价排名工具类（支持多项目）
 */
public class BidRankingUtils {
    // 按项目编号存储的供应商集合 - Map<code, List<SupplierBidInfo>>
    private static final Map<String, List<SupplierBidInfo>> projectSuppliers = new ConcurrentHashMap<>();

    /**
     * 供应商竞价信息
     */
    public static class SupplierBidInfo {
        private Long hid;              // 供应商ID
        private String hName;          // 供应商名称
        private String code;           // 项目编号
        private Double bjTotal;        // 报价
        private Double bjDecline;      // 降幅
        private Integer rank;          // 排名
        private Boolean isWinner;      // 是否中标
        private Date createTime;       //报价时间

        public SupplierBidInfo(Long hid, String hName, String code, Double bjTotal, Double bjDecline,Date createTime) {
            this.hid = hid;
            this.hName = hName;
            this.code = code;
            this.bjTotal = bjTotal;
            this.bjDecline = bjDecline;
            this.rank = 0;
            this.isWinner = false;
            this.createTime = createTime;
        }

        // Getter and Setter methods
        public Long getHid() { return hid; }
        public void setHid(Long hid) { this.hid = hid; }

        public String gethName() { return hName; }
        public void sethName(String hName) { this.hName = hName; }

        public String getCode() { return code; }
        public void setCode(String code) { this.code = code; }

        public Double getBjTotal() { return bjTotal; }
        public void setBjTotal(Double bjTotal) { this.bjTotal = bjTotal; }

        public Double getBjDecline() { return bjDecline; }
        public void setBjDecline(Double bjDecline) { this.bjDecline = bjDecline; }

        public Integer getRank() { return rank; }
        public void setRank(Integer rank) { this.rank = rank; }

        public Boolean getIsWinner() { return isWinner; }
        public void setIsWinner(Boolean isWinner) { this.isWinner = isWinner; }

        public Date getCreateTime() { return createTime; }
        public void setCreateTime(Date createTime) { this.createTime = createTime; }

        @Override
        public String toString() {
            return String.format("Supplier{hid=%d, code=%s, price=%.2f, decline=%.2f%%, rank=%d, winner=%s}",
                    hid, code, bjTotal, bjDecline, rank, isWinner);
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            SupplierBidInfo that = (SupplierBidInfo) o;
            return Objects.equals(hid, that.hid) && Objects.equals(code, that.code);
        }

        @Override
        public int hashCode() {
            return Objects.hash(hid, code);
        }
    }

    /**
     * 竞价排名结果
     */
    public static class BidRankingResult {
        private final Map<Long, SupplierBidInfo> supplierRankMap;  // 供应商排名映射
        private final Long winnerHid;                              // 中标供应商ID
        private final List<SupplierBidInfo> rankedSuppliers;       // 排名后的供应商列表
        private final String projectCode;                          // 项目编号

        public BidRankingResult(Map<Long, SupplierBidInfo> supplierRankMap,
                                Long winnerHid,
                                List<SupplierBidInfo> rankedSuppliers,
                                String projectCode) {
            this.supplierRankMap = supplierRankMap;
            this.winnerHid = winnerHid;
            this.rankedSuppliers = rankedSuppliers;
            this.projectCode = projectCode;
        }

        // Getter methods
        public Map<Long, SupplierBidInfo> getSupplierRankMap() { return supplierRankMap; }
        public Long getWinnerHid() { return winnerHid; }
        public List<SupplierBidInfo> getRankedSuppliers() { return rankedSuppliers; }
        public String getProjectCode() { return projectCode; }

        /**
         * 根据供应商ID获取排名信息
         */
        public SupplierBidInfo getSupplierInfo(Long hid) {
            return supplierRankMap.get(hid);
        }

        /**
         * 获取中标供应商信息
         */
        public SupplierBidInfo getWinnerInfo() {
            return supplierRankMap.get(winnerHid);
        }
    }

    // ================== 项目相关的操作方法 ==================

    /**
     * 初始化项目
     */
    private static void initProjectIfNeeded(String code) {
        projectSuppliers.putIfAbsent(code, new CopyOnWriteArrayList<>());
    }

    /**
     * 获取指定项目的供应商列表
     */
    private static List<SupplierBidInfo> getSuppliersByProject(String code) {
        return projectSuppliers.get(code);
    }

    /**
     * 添加供应商信息到指定项目
     */
    public static boolean addSupplier(SupplierBidInfo supplier) {
        if (supplier == null) {
            throw new IllegalArgumentException("供应商信息不能为空");
        }
        if (supplier.getHid() == null || supplier.getCode() == null) {
            throw new IllegalArgumentException("供应商ID和项目编号不能为空");
        }

        String code = supplier.getCode();
        initProjectIfNeeded(code);
        List<SupplierBidInfo> projectList = getSuppliersByProject(code);

        // 检查是否已存在相同hid和code的供应商
        if (projectList.stream().anyMatch(s ->
                s.getHid().equals(supplier.getHid()) && s.getCode().equals(supplier.getCode()))) {
            return false; // 已存在，不重复添加
        }

        return projectList.add(supplier);
    }

    /**
     * 批量添加供应商信息到指定项目
     */
    public static int addSuppliers(List<SupplierBidInfo> supplierList) {
        if (supplierList == null || supplierList.isEmpty()) {
            return 0;
        }

        int count = 0;
        for (SupplierBidInfo supplier : supplierList) {
            if (addSupplier(supplier)) {
                count++;
            }
        }
        return count;
    }

    /**
     * 根据供应商ID和项目编号删除供应商
     */
    public static boolean removeSupplier(Long hid, String code) {
        if (hid == null || code == null) {
            return false;
        }

        List<SupplierBidInfo> projectList = getSuppliersByProject(code);
        if (projectList == null) {
            return false;
        }

        return projectList.removeIf(supplier ->
                hid.equals(supplier.getHid()) && code.equals(supplier.getCode()));
    }

    /**
     * 删除整个项目的所有供应商
     */
    public static boolean removeProject(String code) {
        if (code == null) {
            return false;
        }
        return projectSuppliers.remove(code) != null;
    }

    /**
     * 根据供应商ID和项目编号获取供应商信息
     */
    public static SupplierBidInfo getSupplierById(Long hid, String code) {
        if (hid == null || code == null) {
            return null;
        }

        List<SupplierBidInfo> projectList = getSuppliersByProject(code);
        if (projectList == null) {
            return null;
        }

        return projectList.stream()
                .filter(supplier -> hid.equals(supplier.getHid()) && code.equals(supplier.getCode()))
                .findFirst()
                .orElse(null);
    }

    /**
     * 获取指定项目的所有供应商
     */
    public static List<SupplierBidInfo> getSuppliersByProjectCode(String code) {
        List<SupplierBidInfo> projectList = getSuppliersByProject(code);
        if (projectList == null) {
            return new ArrayList<>();
        }
        return new ArrayList<>(projectList);
    }

    /**
     * 获取指定供应商参与的所有项目
     */
    public static List<String> getProjectsBySupplier(Long hid) {
        if (hid == null) {
            return new ArrayList<>();
        }

        return projectSuppliers.entrySet().stream()
                .filter(entry -> entry.getValue().stream()
                        .anyMatch(supplier -> hid.equals(supplier.getHid())))
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
    }

    /**
     * 获取所有项目编号
     */
    public static Set<String> getAllProjectCodes() {
        return new HashSet<>(projectSuppliers.keySet());
    }

    /**
     * 更新供应商信息
     */
    public static boolean updateSupplier(SupplierBidInfo updatedSupplier) {
        if (updatedSupplier == null || updatedSupplier.getHid() == null || updatedSupplier.getCode() == null) {
            return false;
        }

        String code = updatedSupplier.getCode();
        List<SupplierBidInfo> projectList = getSuppliersByProject(code);
        if (projectList == null) {
            initProjectIfNeeded(code);
            projectList = getSuppliersByProject(code);
        }

        for (int i = 0; i < projectList.size(); i++) {
            SupplierBidInfo existingSupplier = projectList.get(i);
            if (updatedSupplier.getHid().equals(existingSupplier.getHid()) &&
                    updatedSupplier.getCode().equals(existingSupplier.getCode())) {
                // 更新供应商信息
                existingSupplier.setBjTotal(updatedSupplier.getBjTotal());
                existingSupplier.setBjDecline(updatedSupplier.getBjDecline());
                existingSupplier.setRank(updatedSupplier.getRank());
                existingSupplier.setIsWinner(updatedSupplier.getIsWinner());
                existingSupplier.setCreateTime(updatedSupplier.getCreateTime());
                return true;
            }
        }

        return addSupplier(updatedSupplier);
    }

    /**
     * 更新供应商价格和降幅
     */
    public static boolean updateSupplierBid(Long hid, String code, Double newPrice, Double newDecline) {
        SupplierBidInfo supplier = getSupplierById(hid, code);
        if (supplier == null) {
            return false;
        }

        supplier.setBjTotal(newPrice);
        supplier.setBjDecline(newDecline);
        return true;
    }

    /**
     * 获取指定项目的供应商数量
     */
    public static int getSupplierCountByProject(String code) {
        List<SupplierBidInfo> projectList = getSuppliersByProject(code);
        return projectList != null ? projectList.size() : 0;
    }

    /**
     * 检查供应商是否参与指定项目
     */
    public static boolean containsSupplier(Long hid, String code) {
        return getSupplierById(hid, code) != null;
    }

    // ================== 排名相关方法 ==================

    /**
     * 根据hid和code获取供应商在当前项目中的排名情况
     * @param hid 供应商ID
     * @param code 项目编号
     * @param userPrice 1根据价格排名，2根据降幅排名
     * @return 供应商排名信息，如果不存在返回null
     */
    public static SupplierBidInfo getSupplierRanking(Long hid, String code, Date createTime,int userPrice) {
        if (hid == null || code == null) {
            return null;
        }

        // 先获取供应商基本信息
        SupplierBidInfo supplier = getSupplierById(hid, code);
        if (supplier == null) {
            return null;
        }

        // 重新计算排名以确保数据准确
        List<SupplierBidInfo> projectList = getSuppliersByProject(code);
        if (projectList == null || projectList.isEmpty()) {
            return supplier;
        }

        // 按价格计算排名（算法1的排名逻辑）
        /*List<SupplierBidInfo> sortedByPrice = projectList.stream()
                .sorted(Comparator.comparing(SupplierBidInfo::getBjTotal))
                .collect(Collectors.toList());*/
        List<SupplierBidInfo> sortedByPrice = projectList.stream()
                .sorted(Comparator
                        .comparing(SupplierBidInfo::getBjTotal)
                        .thenComparing(SupplierBidInfo::getCreateTime)
                )
                .collect(Collectors.toList());

        // 查找供应商在价格排名中的位置
        int priceRank = -1;
        for (int i = 0; i < sortedByPrice.size(); i++) {
            if (sortedByPrice.get(i).getHid().equals(hid)) {
                priceRank = i + 1;
                break;
            }
        }

        // 按降幅计算排名（算法2的排名逻辑）
        /*List<SupplierBidInfo> sortedByDecline = projectList.stream()
                .sorted((o1, o2) -> Double.compare(o2.getBjDecline(), o1.getBjDecline()))
                .collect(Collectors.toList());*/
        List<SupplierBidInfo> sortedByDecline = projectList.stream()
                .sorted(Comparator
                        .comparing(SupplierBidInfo::getBjDecline, Comparator.reverseOrder())
                        .thenComparing(SupplierBidInfo::getCreateTime)
                )
                .collect(Collectors.toList());

        // 查找供应商在降幅排名中的位置
        int declineRank = -1;
        for (int i = 0; i < sortedByDecline.size(); i++) {
            if (sortedByDecline.get(i).getHid().equals(hid)) {
                declineRank = i + 1;
                break;
            }
        }

        // 找出价格最低的供应商（中标者）
        SupplierBidInfo priceWinner = projectList.stream()
                .min(Comparator.comparing(SupplierBidInfo::getBjTotal))
                .orElse(null);

        boolean isWinner = priceWinner != null && priceWinner.getHid().equals(hid);

        // 创建包含排名信息的供应商对象（不修改原始对象）
        SupplierBidInfo rankedSupplier = new SupplierBidInfo(
                supplier.getHid(), supplier.gethName(), supplier.getCode(),
                supplier.getBjTotal(), supplier.getBjDecline(),createTime
        );
        rankedSupplier.setRank(userPrice == 1 ? priceRank : declineRank); // 使用价格排名作为主要排名
        rankedSupplier.setIsWinner(isWinner);

        return rankedSupplier;
    }

    /**
     * 获取供应商在指定项目中的详细排名信息
     * @param hid 供应商ID
     * @param code 项目编号
     * @return 包含价格排名和降幅排名的Map，如果不存在返回空Map
     */
    public static Map<String, Object> getSupplierDetailedRanking(Long hid, String code) {
        Map<String, Object> rankingInfo = new HashMap<>();

        SupplierBidInfo supplier = getSupplierById(hid, code);
        if (supplier == null) {
            return rankingInfo;
        }

        List<SupplierBidInfo> projectList = getSuppliersByProject(code);
        if (projectList == null || projectList.isEmpty()) {
            return rankingInfo;
        }

        // 计算价格排名
        /*List<SupplierBidInfo> sortedByPrice = projectList.stream()
                .sorted(Comparator.comparing(SupplierBidInfo::getBjTotal))
                .collect(Collectors.toList());*/
        List<SupplierBidInfo> sortedByPrice = projectList.stream()
                .sorted(Comparator
                        .comparing(SupplierBidInfo::getBjTotal)
                        .thenComparing(SupplierBidInfo::getCreateTime)
                )
                .collect(Collectors.toList());

        int priceRank = -1;
        for (int i = 0; i < sortedByPrice.size(); i++) {
            if (sortedByPrice.get(i).getHid().equals(hid)) {
                priceRank = i + 1;
                break;
            }
        }

        // 计算降幅排名
        /*List<SupplierBidInfo> sortedByDecline = projectList.stream()
                .sorted((o1, o2) -> Double.compare(o2.getBjDecline(), o1.getBjDecline()))
                .collect(Collectors.toList());*/
        List<SupplierBidInfo> sortedByDecline = projectList.stream()
                .sorted(Comparator
                        .comparing(SupplierBidInfo::getBjDecline, Comparator.reverseOrder())
                        .thenComparing(SupplierBidInfo::getCreateTime)
                )
                .collect(Collectors.toList());

        int declineRank = -1;
        for (int i = 0; i < sortedByDecline.size(); i++) {
            if (sortedByDecline.get(i).getHid().equals(hid)) {
                declineRank = i + 1;
                break;
            }
        }

        // 检查是否中标
        SupplierBidInfo priceWinner = projectList.stream()
                .min(Comparator.comparing(SupplierBidInfo::getBjTotal))
                .orElse(null);
        boolean isWinner = priceWinner != null && priceWinner.getHid().equals(hid);

        rankingInfo.put("supplier", supplier);
        rankingInfo.put("priceRank", priceRank);
        rankingInfo.put("declineRank", declineRank);
        rankingInfo.put("isWinner", isWinner);
        rankingInfo.put("totalSuppliers", projectList.size());
        rankingInfo.put("lowestPrice", priceWinner != null ? priceWinner.getBjTotal() : null);
        rankingInfo.put("highestDecline", sortedByDecline.get(0).getBjDecline());

        return rankingInfo;
    }

    /**
     * 算法1：根据价格进行从小到大排名，排名第一的供应商中标
     */
    public static BidRankingResult rankByPrice(String code) {
        List<SupplierBidInfo> projectList = getSuppliersByProject(code);
        if (projectList == null || projectList.isEmpty()) {
            throw new IllegalArgumentException("项目" + code + "的供应商竞价列表不能为空");
        }

        // 按价格从小到大排序
        /*List<SupplierBidInfo> sortedByPrice = projectList.stream()
                .sorted(Comparator.comparing(SupplierBidInfo::getBjTotal))
                .collect(Collectors.toList());*/

        List<SupplierBidInfo> sortedByPrice = projectList.stream()
                .sorted(Comparator
                        .comparing(SupplierBidInfo::getBjTotal)
                        .thenComparing(SupplierBidInfo::getCreateTime)
                )
                .collect(Collectors.toList());

        // 构建排名映射和设置排名
        Map<Long, SupplierBidInfo> rankMap = new HashMap<>();
        Long winnerHid = null;
        Double minPrice = Double.MAX_VALUE;

        for (int i = 0; i < sortedByPrice.size(); i++) {
            SupplierBidInfo supplier = sortedByPrice.get(i);
            supplier.setRank(i + 1);

            // 找出价格最低的供应商（排名第一的）
            if (i == 0 || supplier.getBjTotal() < minPrice) {
                winnerHid = supplier.getHid();
                minPrice = supplier.getBjTotal();
            }

            // 设置中标标志
            supplier.setIsWinner(supplier.getHid().equals(winnerHid));

            rankMap.put(supplier.getHid(), supplier);
        }

        return new BidRankingResult(rankMap, winnerHid, sortedByPrice, code);
    }

    /**
     * 算法2：根据降幅从大到小排名（用于展示），但根据价格最低确定中标
     */
    public static BidRankingResult rankByDeclineWithPriceWinner(String code) {
        List<SupplierBidInfo> projectList = getSuppliersByProject(code);
        if (projectList == null || projectList.isEmpty()) {
            throw new IllegalArgumentException("项目" + code + "的供应商竞价列表不能为空");
        }

        // 按降幅从大到小排序（用于展示排名）
        /*List<SupplierBidInfo> sortedByDecline = projectList.stream()
                .sorted((o1, o2) -> Double.compare(o2.getBjDecline(), o1.getBjDecline()))
                .collect(Collectors.toList());*/
        List<SupplierBidInfo> sortedByDecline = projectList.stream()
                .sorted(Comparator
                        .comparing(SupplierBidInfo::getBjDecline, Comparator.reverseOrder())
                        .thenComparing(SupplierBidInfo::getCreateTime)
                )
                .collect(Collectors.toList());

        // 找出价格最低的供应商（实际中标者）
        SupplierBidInfo priceWinner = projectList.stream()
                .min(Comparator.comparing(SupplierBidInfo::getBjTotal))
                .orElseThrow(() -> new RuntimeException("项目" + code + "未找到中标供应商"));

        // 构建排名映射
        Map<Long, SupplierBidInfo> rankMap = new HashMap<>();

        for (int i = 0; i < sortedByDecline.size(); i++) {
            SupplierBidInfo supplier = sortedByDecline.get(i);
            supplier.setRank(i + 1);

            // 设置中标标志（根据价格最低）
            supplier.setIsWinner(supplier.getHid().equals(priceWinner.getHid()));

            rankMap.put(supplier.getHid(), supplier);
        }

        return new BidRankingResult(rankMap, priceWinner.getHid(), sortedByDecline, code);
    }

    /**
     * 测试用例和示例用法
     */
    public static void main(String[] args) {
        // 清空数据
        projectSuppliers.clear();

        // 添加多个项目的供应商信息
        addSuppliers(Arrays.asList(
                new SupplierBidInfo(1001L, "","PROJ001", 950000.0, 5.2,new Date()),
                new SupplierBidInfo(1002L, "","PROJ001", 920000.0, 3.8,new Date()),
                new SupplierBidInfo(1003L, "","PROJ001", 980000.0, 4.5,new Date()),
                new SupplierBidInfo(1004L, "","PROJ001", 910000.0, 7.2,new Date()),

                new SupplierBidInfo(1001L, "","PROJ002", 850000.0, 8.2,new Date()),
                new SupplierBidInfo(1002L, "","PROJ002", 820000.0, 9.8,new Date()),
                new SupplierBidInfo(1005L, "","PROJ002", 880000.0, 7.5,new Date())
        ));

        System.out.println("=== 测试获取供应商排名情况 ===");

        // 测试获取单个供应商排名
        Long testHid = 1002L;
        String testCode = "PROJ001";

        System.out.println("\n1. 获取供应商" + testHid + "在项目" + testCode + "中的排名:");
        SupplierBidInfo ranking = getSupplierRanking(testHid, testCode,new Date(),1);
        if (ranking != null) {
            System.out.println("   排名信息: " + ranking);
        } else {
            System.out.println("   未找到该供应商在该项目中的信息");
        }

        // 测试获取详细排名信息
        System.out.println("\n2. 获取供应商" + testHid + "在项目" + testCode + "中的详细排名:");
        Map<String, Object> detailedRanking = getSupplierDetailedRanking(testHid, testCode);
        if (!detailedRanking.isEmpty()) {
            System.out.println("   价格排名: " + detailedRanking.get("priceRank") + "/" + detailedRanking.get("totalSuppliers"));
            System.out.println("   降幅排名: " + detailedRanking.get("declineRank") + "/" + detailedRanking.get("totalSuppliers"));
            System.out.println("   是否中标: " + detailedRanking.get("isWinner"));
            System.out.println("   最低价格: " + detailedRanking.get("lowestPrice"));
            System.out.println("   最高降幅: " + detailedRanking.get("highestDecline"));
        }

        // 测试不存在的供应商
        System.out.println("\n3. 测试不存在的供应商:");
        SupplierBidInfo notExist = getSupplierRanking(9999L, "PROJ001",new Date(),1);
        System.out.println("   结果: " + (notExist == null ? "未找到" : notExist));

        // 测试不存在的项目
        System.out.println("\n4. 测试不存在的项目:");
        SupplierBidInfo notExistProject = getSupplierRanking(1001L, "NOT_EXIST",new Date(),1);
        System.out.println("   结果: " + (notExistProject == null ? "未找到" : notExistProject));
    }

    private static void printResult(BidRankingResult result) {
        System.out.println("项目: " + result.getProjectCode());
        System.out.println("中标供应商: " + result.getWinnerInfo());
        System.out.println("完整排名:");
        for (SupplierBidInfo supplier : result.getRankedSuppliers()) {
            System.out.println("  " + supplier);
        }
    }
}
